package com.clkj.xiuzheng.service.shangcheng;

import com.clkj.xiuzheng.dao.shangcheng.*;
import com.clkj.xiuzheng.pojo.Product;
import com.clkj.xiuzheng.pojo.common.DateFormatHelper;
import com.clkj.xiuzheng.pojo.common.OSSUtil;
import com.clkj.xiuzheng.pojo.common.Result;
import com.clkj.xiuzheng.pojo.common.StatusCode;
import com.clkj.xiuzheng.pojo.shangcheng.*;
import com.clkj.xiuzheng.pojo.shangcheng.vo.HealthUserVo;
import com.clkj.xiuzheng.pojo.shangcheng.vo.HealthVo;
import com.clkj.xiuzheng.pojo.shangcheng.vo.HomeVo;
import com.clkj.xiuzheng.pojo.shangcheng.vo.RateVo;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.tomcat.util.threads.ThreadPoolExecutor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartRequest;
import tk.mybatis.mapper.entity.Example;

import javax.servlet.http.HttpServletRequest;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Service
public class SystemServiceImpl implements SystemService{



    @Autowired
    private BannerMapper bannerMapper;
    @Autowired
    private NoticeMapper noticeMapper;
    @Autowired
    private ScProductMapper scProductMapper;
    @Autowired
    private TopicOrVideoMapper topicOrVideoMapper;
    @Autowired
    private ScProductformatMapper scProductformatMapper;
    @Autowired
    private ScProductimageMapper  scProductimageMapper;
    @Autowired
    private ScUserMapper scUserMapper;
    @Autowired
    private ScCompanyMapper scCompanyMapper;
    @Autowired
    private ScOrderMapper scOrderMapper;
    @Autowired
    private PromoterApplyMapper promoterApplyMapper;
    @Autowired
    private HealthMapper healthMapper;
    @Autowired
    private HealthUserMapper healthUserMapper;
    @Autowired
    private UserScoreMapper userScoreMapper;
    @Autowired
    private ScOrderInfoMapper scOrderInfoMapper;


    private final ThreadPoolExecutor executor = new ThreadPoolExecutor(
            10,
            50,
            60,
            TimeUnit.SECONDS,
            new LinkedBlockingQueue<>(100000),
            Executors.defaultThreadFactory(),
            new ThreadPoolExecutor.AbortPolicy());
    @Autowired
    private ScFactoryMapper scFactoryMapper;


    @Override
    public void addNotice(Notice notice) {
        if (notice.getNoticeId()!=null){
            notice.setIsRelease(1);
            noticeMapper.updateByPrimaryKeySelective(notice);
            return;
        }
        notice.setCreatedTime(DateFormatHelper.currentTimes());
        notice.setNoticeStatus(0);
        notice.setCompanyReview(0);
        notice.setMainCompanyReview(0);
        noticeMapper.insertSelective(notice);
    }

    @Override
    public PageInfo listNotice(Integer page, Integer size, Integer companyId, Integer flag) {
        PageHelper.startPage(page,size);
        if (companyId==1){
            Example example = new Example(Notice.class);
            example.orderBy("createdTime").desc();
            if (flag!=null&&flag!=3){
                example.createCriteria().andEqualTo("userType",flag);
            }
            List<Notice> notices = noticeMapper.selectByExample(example);
            return new PageInfo(notices);
        }
        Example example = new Example(Notice.class);
        example.orderBy("createdTime").desc();
        example.createCriteria().andEqualTo("companyId",companyId);
        if (flag!=null&&flag!=3){
            example.createCriteria().andEqualTo("userType",flag);
        }
        List<Notice> notices = noticeMapper.selectByExample(example);
        return new PageInfo(notices);
    }

    @Override
    public void releaseNotice(Integer id, Integer status,String dateTime) {
        Notice notice= new Notice();
        notice.setNoticeId(id);
        notice.setIsRelease(status);
        notice.setReleaseTime(dateTime);
        noticeMapper.updateByPrimaryKeySelective(notice);
    }

    @Override
    public void addBanner(Banner banner, HttpServletRequest request) {
        MultipartFile file = ((MultipartRequest) request).getFile("mainPic");
        String picture = OSSUtil.uploadingImg(file, "xiuzheng/scLunbo");
        banner.setPictureAddress(picture);
        banner.setPictureStatus(1);
        bannerMapper.insertSelective(banner);
    }

    @Override
    public List<Banner> getBanner() {
        String today = DateFormatHelper.today();
        List<Banner> banners = bannerMapper.getBanner(today);
        return banners;
    }

    @Override
    public void updateBanner(Banner banner, HttpServletRequest request) {
        MultipartFile file = ((MultipartRequest) request).getFile("mainPic");
        if (file !=null) {
            String picture = OSSUtil.uploadingImg(file, "xiuzheng/scLunbo");
            banner.setPictureAddress(picture);
            banner.setPictureStatus(1);
        }
//        if (banner.getBandingId() == 0){
//            banner.setBannerId(null);
//        }
        bannerMapper.updateByPrimaryKeySelective(banner);
    }

    @Override
    public PageInfo listBanner(Integer page, Integer size) {
        PageHelper.startPage(size,page);
        List<Banner> banners = bannerMapper.getlistBanner();
        banners.forEach(banner -> {
            if (banner.getFlag()==0){
             Example example = new Example(SProduct.class);
             Example.Criteria criteria = example.createCriteria();
             criteria.andEqualTo("productId",banner.getBandingId());
                SProduct sProduct = scProductMapper.selectOneByExample(example);
                banner.setBandingName(sProduct.getProductName());
            }else if (banner.getFlag()==1 || banner.getFlag()==2){
                Example example = new Example(TopicOrVideo.class);
                Example.Criteria criteria = example.createCriteria();
                criteria.andEqualTo("baikeId",banner.getBandingId());
                TopicOrVideo topicOrVideo = topicOrVideoMapper.selectOneByExample(example);
                banner.setBandingName(topicOrVideo.getBaikeTitle());
            }else if (banner.getFlag()==-1){
               banner.setBandingName("无绑定商品或文章");
            }else if (banner.getFlag()==3){
               banner.setBandingName("绑定跳转链接");
            }
        });
        return new PageInfo(banners);
    }

    @Override
    public Result getBandingByType(Integer type,String name) {
        List<Map<String,Object>> list = new ArrayList<>();

        if (type == 0){
            Example example = new Example(SProduct.class);
            Example.Criteria criteria = example.createCriteria();
            criteria.andEqualTo("productStatus",1);
            criteria.andCondition("product_name like '%"+name+"%'");
            scProductMapper.selectByExample(example).forEach(product -> {
                Integer productId = product.getProductId();
                String productName = product.getProductName();
                Map<String,Object> map = new HashMap();
                map.put("bandingId",productId);
                map.put("bandingName",productName);
                list.add(map);
            });
        }else if (type == 1){
            Example example = new Example(TopicOrVideo.class);
            Example.Criteria criteria = example.createCriteria();
            criteria.andEqualTo("baikeStatus",1);
            criteria.andEqualTo("baikeType",0);
            criteria.andCondition("baike_title like '%"+name+"%'");
            List<TopicOrVideo> topicOrVideos = topicOrVideoMapper.selectByExample(example);
            topicOrVideos.forEach(topicOrVideo -> {
                Integer baikeId = topicOrVideo.getBaikeId();
                String baikeTitle = topicOrVideo.getBaikeTitle();
                Map<String,Object> map = new HashMap();
                map.put("bandingId",baikeId);
                map.put("bandingName",baikeTitle);
                list.add(map);
            });
        }else if (type == 2){
            Example example = new Example(TopicOrVideo.class);
            Example.Criteria criteria = example.createCriteria();
            criteria.andEqualTo("baikeStatus",1);
            criteria.andEqualTo("baikeType",1);
            criteria.andCondition("baike_title like '%"+name+"%'");
            List<TopicOrVideo> topicOrVideos = topicOrVideoMapper.selectByExample(example);
            topicOrVideos.forEach(topicOrVideo -> {
                Integer baikeId = topicOrVideo.getBaikeId();
                String baikeTitle = topicOrVideo.getBaikeTitle();
                Map<String,Object> map = new HashMap();
                map.put("bandingId",baikeId);
                map.put("bandingName",baikeTitle);
                list.add(map);
            });
        }
        return new Result(true, StatusCode.OK,"查询成功",list);
    }

    @Override
    public void updateStatus(String ids, Integer status) {
        String[] Ids = ids.split(",");
        Example example = new Example(Banner.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andIn("bannerId", Arrays.asList(Ids));
        Banner banner = new Banner();
        banner.setPictureStatus(status);
        bannerMapper.updateByExampleSelective(banner,example);
    }

    @Override
    public Result getBandingById(Integer bandingId, Integer flag) {
        if (flag == 0){
            //根据id查询获取商品详情信息
            //查询商品详情
            SProduct product = scProductMapper.getProductById(bandingId);
            //根据商品id查询商品下的规格信息
            Example example1 =  new Example(ProductFormat.class);
            Example.Criteria criteria1 = example1.createCriteria();
            criteria1.andEqualTo("productId",bandingId);
            criteria1.andEqualTo("isDeleted",1);
            List<ProductFormat> productFormats = scProductformatMapper.selectByExample(example1);
            product.setProductFormat(productFormats);
            //根据商品id查询商品轮播图
            Example example2 =  new Example(ProductImage.class);
            Example.Criteria criteria2 = example2.createCriteria();
            criteria2.andEqualTo("productId",bandingId);
            criteria2.andEqualTo("imageType",0);
            product.setLunboImage(scProductimageMapper.selectByExample(example2));
            //根据商品id查询商品详情图
            Example example3 =  new Example(ProductImage.class);
            Example.Criteria criteria3 = example3.createCriteria();
            criteria3.andEqualTo("productId",bandingId);
            criteria3.andEqualTo("imageType",1);
            product.setDetailImage(scProductimageMapper.selectByExample(example3));
            return new Result(true,StatusCode.OK,"查询成功",product);
        }else if (flag == 1 || flag == 2){
            //根据文章或视频id查询获取文章详情信息
            TopicOrVideo topicOrVideo = new TopicOrVideo();
            topicOrVideo.setBaikeId(bandingId);
            TopicOrVideo topicOrVideo1 = topicOrVideoMapper.selectByPrimaryKey(topicOrVideo);
            return new Result(true,StatusCode.OK,"查询成功",topicOrVideo1);
        }
        return new Result(false, StatusCode.ERROR, "操作失败");
    }

    @Override
    public HomeVo getHomeData(Integer companyId) {
        HomeVo homeVo = new HomeVo();
        //根据父级公司查出子级公司id
        List<Integer> companyIds = scCompanyMapper.getCompanyId(companyId);
        companyIds.add(companyId);
        CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> {
            Integer totalUserNum =0;
            for (Integer id : companyIds) {
                //查询子级公司用户数
                Integer userNum = scUserMapper.getUserNum(id);
                totalUserNum += userNum;
            }
            return totalUserNum;
        }, executor);
        String today = DateFormatHelper.today();
        // 解析字符串为 LocalDate
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        LocalDate date = LocalDate.parse(today, formatter);
        // 获取这个月的第一天
        LocalDate firstDayOfMonth = date.withDayOfMonth(1);
        // 获取这个月的最后一天
        LocalDate lastDayOfMonth = date.withDayOfMonth(date.lengthOfMonth());
        //订单总额
        CompletableFuture<Double> future2 = CompletableFuture.supplyAsync(() -> {
            Double OrderTotal = scOrderMapper.selectOrderTotal(companyId);
            return OrderTotal;
        }, executor);

        //今日订单总额
        CompletableFuture<Double> future3 = CompletableFuture.supplyAsync(() -> {
            Double todayOrderTotal = scOrderMapper.selectTodayOrderTotal(companyId, firstDayOfMonth.toString(), lastDayOfMonth.toString());
            return todayOrderTotal;
        }, executor);
        //订单总数
        CompletableFuture<Integer> future4 = CompletableFuture.supplyAsync(() -> {
            Integer orderNum = scOrderMapper.selectOrderNum(companyId);
            return orderNum;
        }, executor);
        //今日订单数
        CompletableFuture<Integer> future5 = CompletableFuture.supplyAsync(() -> {
            Integer todayOrderNum = scOrderMapper.selectTodayOrderNum(companyId, firstDayOfMonth.toString(), lastDayOfMonth.toString());
            return todayOrderNum;
        }, executor);
        //获取本周每日订单数
        // 获取当前日期
        LocalDate currentDate = LocalDate.now();
        Map<Integer, Object> orderWeek = new HashMap<>();
            //获取本周每日订单数
            LocalDate weekDay = currentDate.with(DayOfWeek.MONDAY);
            for (int i = 1; i <= 7; i++){
                Integer orderByWeekDate = scOrderMapper.selectOrderByWeekDate(companyId,weekDay.toString(),weekDay.plusDays(1).toString());
                orderWeek.put(i,orderByWeekDate);
                weekDay=weekDay.plusDays(1);
        }
        Map<Integer, Object> userWeek = new HashMap<>();

            //获取本周每月用户数
            LocalDate weekDay2 = currentDate.with(DayOfWeek.MONDAY);
            for (int i = 1; i <= 7; i++) {
                Integer userNumMonth = 0;
                Integer vipNum = 0;
                Integer promoNum = 0;
                for (Integer id : companyIds) {
                    //查询子级公司用户数
                    userNumMonth += scUserMapper.getUserNumByMonth(id,weekDay2.toString(),weekDay2.plusDays(1).toString(),0);
                    vipNum += scUserMapper.getUserNumByMonth(id,weekDay2.toString(),weekDay2.plusDays(1).toString(),1);
                    promoNum += scUserMapper.getUserNumByMonth(id,weekDay2.toString(),weekDay2.plusDays(1).toString(),2);
                }
                List<Integer> list = new ArrayList<>();
                list.add(userNumMonth);
                list.add(vipNum);
                list.add(promoNum);
                userWeek.put(i,list);
                weekDay2=weekDay2.plusDays(1);
            }
        //获取成为推广员列表
        List<PromoterApply> promoUserListAll = new ArrayList<>();
        Example example = new Example(ProductCompany.class);
        example.createCriteria().andEqualTo("companyId",companyId);
        ProductCompany productCompany = scCompanyMapper.selectOneByExample(example);
        if (productCompany.getParentId()==0){
            for (Integer id : companyIds) {
                //查询子级公司用户数
                List<PromoterApply> promoUserList = promoterApplyMapper.getPromoUserList(id);
                promoUserListAll.addAll(promoUserList);
            }
        }else {
            List<PromoterApply> promoUserList = promoterApplyMapper.getPromoUserListById(companyId);
            promoUserListAll.addAll(promoUserList);
        }
        //获取全部订单
        List<Order> orderListAll = new ArrayList<>();
        for (Integer id : companyIds) {
            //查询子级公司用户数
            List<Order> orderList = scOrderMapper.getOrderList(id);
            orderListAll.addAll(orderList);
        }
        //获取销售比率
        List<RateVo> rateVo = null;
        if (productCompany.getParentId()==0){
            rateVo = scOrderMapper.getRateVo(companyId);
        }
        //获取总积分消耗
        float usedScore  = userScoreMapper.getUsedScore();
        //获取总积分剩余
        float remainScore = userScoreMapper.getRemainScore();
        //获取总余额剩余
        double usedMoney = userScoreMapper.getUsedMoney();
        homeVo.setTotalUserNum(future1.join());
        homeVo.setOrderTotal(future2.join());
        homeVo.setTodayOrderTotal(future3.join());
        homeVo.setOrderNum(future4.join());
        homeVo.setTodayOrderNum(future5.join());
        homeVo.setOrderWeek(orderWeek);
        homeVo.setUserWeek(userWeek);
        homeVo.setPromoUserListAll(promoUserListAll);
        homeVo.setOrderListAll(orderListAll);
        homeVo.setRateVo(rateVo);
        homeVo.setUsedScore(usedScore);
        homeVo.setRemainScore(remainScore);
        homeVo.setUsedMoney(usedMoney);
        return homeVo;
    }

    @Override
    public Map<Integer, Object> getHomeDataOrderMonth(Integer companyId) {
        //获取本月每日订单数
        // 获取当前日期
        String today = DateFormatHelper.today();
        // 解析字符串为 LocalDate
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        LocalDate date = LocalDate.parse(today, formatter);
        Map<Integer, Object> orderMonth = new HashMap<>();
        for (int i = 1; i <= date.lengthOfMonth(); i++) {
            String currentDay = date.withDayOfMonth(i).toString();
            String nextDay = (i < date.lengthOfMonth()) ? date.withDayOfMonth(i + 1).toString() : null;
            Integer orderByMonthDate = scOrderMapper.selectOrderByMonthDate(companyId, currentDay, nextDay);
            orderMonth.put(i, orderByMonthDate);
        }
        return orderMonth;
    }

    @Override
    public Map<Integer, Object> getHomeDataUserMonth(Integer companyId) {
        List<Integer> companyIds = scCompanyMapper.getCompanyId(companyId);
        Map<Integer, Object> userMonth = new HashMap<>();
        //获取本月每日订单数
        // 获取当前日期
        String today = DateFormatHelper.today();
        // 解析字符串为 LocalDate
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        LocalDate date = LocalDate.parse(today, formatter);
            //获取本月每日用户数
            for (int i = 1; i <= date.lengthOfMonth(); i++) {
                String currentDay = date.withDayOfMonth(i).toString();
                String nextDay = (i < date.lengthOfMonth()) ? date.withDayOfMonth(i + 1).toString() : null;
                Integer userNumMonth = 0;
                Integer vipNum = 0;
                Integer promoNum = 0;
                if (companyId==1){
                    userNumMonth += scUserMapper.getUserNumByMonth(0, currentDay, nextDay, 0);
                    vipNum += scUserMapper.getUserNumByMonth(1, currentDay, nextDay, 1);
                    promoNum += scUserMapper.getUserNumByMonth(2, currentDay, nextDay, 2);
                }else {
                    //查询子级公司用户数
                    userNumMonth += scUserMapper.getUserNumByMonth(companyId, currentDay, nextDay, 0);
                    vipNum += scUserMapper.getUserNumByMonth(companyId, currentDay, nextDay, 1);
                    promoNum += scUserMapper.getUserNumByMonth(companyId, currentDay, nextDay, 2);
                }
                List<Integer> list = new ArrayList<>();
                list.add(userNumMonth);
                list.add(vipNum);
                list.add(promoNum);
                userMonth.put(i, list);
            }
            return userMonth;

    }

    @Override
    public List<Health> listHealth() {
        return healthMapper.selectAll();
    }

    @Override
    public void deleteHealth(String ids) {
        Example example = new Example(Health.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andIn("healthId",Arrays.asList(ids.split(",")));
        healthMapper.deleteByExample(example);
    }

    @Override
    public void addHealthUser(String healthIds,String answerIds,Integer userId) {

        Example example = new Example(HealthUser.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("userId",userId);
        healthUserMapper.deleteByExample(example);
        HealthUser healthUser =null;
        List<HealthUser> userList = new ArrayList<>();
        String [] ids = healthIds.split(",");
        String [] answer = answerIds.split(",");
        for (int i = 0; i < ids.length; i++) {
            healthUser = new HealthUser();
            healthUser.setHealthId(Integer.parseInt(ids[i]));
            healthUser.setUserId(userId);
            healthUser.setUserAnswer(Integer.parseInt(answer[i]));
            userList.add(healthUser);
        }
        healthUserMapper.insertList(userList);

    }

    @Override
    public List<Health> listHealthUser(Integer userId) {
        return healthMapper.listUserHealth(userId);
    }

    @Override
    public void addHealth(HealthVo healthVo) {
        healthMapper.insertList(healthVo.getHealthList());
    }

    public void reviewNotice(Integer noticeId, Integer companyId) {
        Example example = new Example(Notice.class);
        example.createCriteria().andEqualTo("noticeId",noticeId);
        Notice notice = noticeMapper.selectOneByExample(example);
        if (notice.getCompanyId()==0){
            notice.setMainCompanyReview(1);
            notice.setCompanyReview(1);
            notice.setNoticeStatus(1);
            noticeMapper.updateByPrimaryKeySelective(notice);
            return;
        }
        if (companyId==1){
            notice.setMainCompanyReview(1);
            if (notice.getCompanyReview()==1){
                notice.setNoticeStatus(1);
            }
        }else {
            notice.setCompanyReview(1);
            if (notice.getMainCompanyReview()==1){
                notice.setNoticeStatus(1);
            }
        }
        noticeMapper.updateByPrimaryKeySelective(notice);
    }

    @Override
    public Map getSalesByFactoryId() {
        //获取所有厂商信息
        List<ProductFactory> productFactories = scFactoryMapper.selectAll();
        Map map = new HashMap();
        for (ProductFactory productFactory : productFactories) {
            //获取厂商订单数
            Integer orderNum = scOrderMapper.getSalesByFactoryId(productFactory.getFactoryId());
            if (orderNum==null){
                orderNum = 0;
            }
            map.put(productFactory.getFactoryName(),orderNum);
        }
    return map;
    }

    @Override
    public Map  getSalesByProductId(Integer productId) {
    Example example = new Example(ProductFormat.class);
    Example.Criteria criteria = example.createCriteria();
    criteria.andEqualTo("productId",productId);
    List<ProductFormat> productFormats = scProductformatMapper.selectByExample(example);
    Map map = new HashMap();
    productFormats.forEach(productFormat -> {
        //获取厂商订单数
        Integer orderNum = scOrderMapper.getSalesByProductId(productFormat.getFormatId());
        if (orderNum==null){
            orderNum = 0;
        }
        map.put(productFormat.getFormatName(),orderNum);
    });
        return map;
    }
}
